package com.fingard.dsp.bank.directbank.spdb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Calendar;
import java.util.Date;

public class SPDB01Transaction extends SPDB01Base implements ITransaction {
    //采用流处理方式
    //1、循环调用readRecord()读取一个请求明细，然后写入发银行的XML对象
    //2、发银行
    //3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
    //   然后调用writeRetDetail()，写入返回ATS的明细
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        if (StringHelper.hasAnyChar(p_req7516.actNum) && p_req7516.actNum.substring(0, 3).equals("OSA")) {
            return d_7516_HisTrans_OSA(p_req7516);
        } else {
            return d_7516_HisTrans_NoOSA(p_req7516);
        }
    }

    private RetAtsTrans d_7516_HisTrans_OSA(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
        retAtsTrans.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        try {
            //起始日期
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());
            //结束日期
            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while (tmpIntDateFrom <= tmpIntDateTo && StringHelper.isNullOrEmpty(tmpRespCode)) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //当是跨月查询时，先查询起始日期到月末日期记录，再查询月末后一天日期到结束日期记录
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }
                int startNumber = 1;//查询起始数
                int totalNumber = 0;//总查询数
                int qryNumber = 20;//每次查询数
                while (startNumber == 1 || totalNumber >= startNumber) {
                    //拼接请求报文体
                    SPDB01Header tmpBnkHeader = new SPDB01Header();
                    tmpBnkHeader.transCode = "E104";
                    XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    xmlWriter.autoFormat = false;
                    xmlWriter.writeStartElement("body");
                    //根据传入的离岸账户查询对账户所属的离岸客户号，赋值到表体transMasterID中，否则不进行赋值
                    xmlWriter.writeElementString("transMasterID", getBankConfig().getMapValueByKey("transMasterIDMapping", p_req7516.actNum));//备用字段
                    xmlWriter.writeElementString("acctNo", p_req7516.actNum);
                    xmlWriter.writeElementString("beginDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    xmlWriter.writeElementString("endDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));
                    xmlWriter.writeElementString("beginNumber", startNumber + "");
                    xmlWriter.writeElementString("queryNumber", qryNumber + "");
                    xmlWriter.writeEndDocument();
                    String[] tmpStrRet = sendToBankOSA(xmlWriter.toXmlString(), tmpBnkHeader);

                    //处理响应报文
                    if (tmpStrRet[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String returnCode = tmpBkReader.getFirstTextNotNull("/packet/head/returnCode");
                            String returnMsg = tmpBkReader.getFirstTextNotNull("/packet/head/returnMsg");
                            if (StringHelper.isNullOrEmpty(returnMsg)) {
                                returnMsg = tmpBkReader.getFirstTextNotNull("/packet/body/returnMsg");
                            }
                            if (returnCode != null && returnCode.equals("AAAAAAA")) {
                                totalNumber = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/packet/body/totalNumber"));
                                String cur = convertCurToATS(tmpBkReader.getFirstTextNotNull("/packet/body/currency"));
                                if (cur.equals(p_req7516.actCur)) {
                                    while (tmpBkReader.read("/packet/body/lists/list")) {
                                        XElement readXElement = tmpBkReader.readedXElement;
                                        RetAtsTransDetail detail = new RetAtsTransDetail();
                                        detail.actArea = p_req7516.actArea;
                                        detail.actNum = p_req7516.actNum;
                                        detail.tranDate = DateHelper.convertD8toD10(readXElement.getSingleTextNotNull("tllyDate").trim());
                                        detail.valueDate = DateHelper.convertD8toD10(readXElement.getSingleTextNotNull("valueDate").trim());
                                        detail.tranTime = detail.valueDate + " 00:00:00";
                                        detail.cur = cur;//币种
                                        detail.accBal = readXElement.getSingleTextNotNull("balance").trim().replaceAll(",", "");//账户余额
                                        String note = readXElement.getSingleTextNotNull("note").trim();
                                        detail.usage = note;
                                        //DSPJAVA-11767 【君康人寿】浦发明细问题/Fantx@2020年4月23日
                                        nodeAnalysic(tmpBkReader.readedXElement, detail, getCharset());//根据配置将 银行返回字段summary 分割赋值给对账码和用途
                                        detail.askNumber = readXElement.getSingleTextNotNull("tllySeqNo").trim();//银行流水号
                                        detail.originator = readXElement.getSingleTextNotNull("receiptNo").trim();//业务号
                                        String dAmount = readXElement.getSingleTextNotNull("debitAmount").trim().replaceAll(",", "");//借方金额
                                        String cAmount = readXElement.getSingleTextNotNull("creditAmount").trim().replaceAll(",", "");//贷方金额
                                        if (StringHelper.hasAnyChar(dAmount) && Double.parseDouble(dAmount) > 0) {
                                            if (dAmount.startsWith("-")) {
                                                detail.cdFlag = "2";
                                                detail.tranAmt = dAmount.substring(1);
                                            } else {
                                                detail.cdFlag = "1";
                                                detail.tranAmt = dAmount;
                                            }
                                        } else if (StringHelper.hasAnyChar(cAmount) && Double.parseDouble(cAmount) > 0) {
                                            if (cAmount.startsWith("-")) {
                                                detail.cdFlag = "1";
                                                detail.tranAmt = cAmount.substring(1);
                                            } else {
                                                detail.cdFlag = "2";
                                                detail.tranAmt = cAmount;
                                            }
                                        }
                                        retAtsTrans.writeRetDetail(detail);
                                    }
                                }
                            } else if ("OSA1040".equals(returnCode)) {//没有数据报的错
                                tmpRespCode = "0";
                                tmpRespInfo = returnMsg;
                                break;
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = returnMsg;
                                break;
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpSbMsg.toString();
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpStrRet[1];
                        break;
                    }
                    startNumber += qryNumber;//不管实际返回多少，都加20（如果查询数20，而实际返回不到20，则说明到最后一页，或者系统异常）
                }
                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception ex) {
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            ex.printStackTrace();
            WriteBankLogLn("查询明细异常:" + ex);
        }
        if ("-1".equals(tmpRespCode)) {
            retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
            retAtsTrans.writeStart();//写返回ATS的统一头部信息
            retAtsTrans.writeRespCode(tmpRespCode);
            retAtsTrans.writeRespInfo(tmpRespInfo);
        } else if (retAtsTrans.getWrittenRdCount() == 0) {
            retAtsTrans.writeRespInfo("交易为空");
            retAtsTrans.writeRespCode("0");
        }
        retAtsTrans.writeEnd();
        return retAtsTrans;
    }

    private RetAtsTrans d_7516_HisTrans_NoOSA(Req7516HisTrans p_req7516) throws Exception {
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            //tmpClndrStepTo.get(Calendar.MONTH) MONTH是从0开始编的，意味着0是1月，11是12月
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            //按自然月循环查询
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //判断是否跨月
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    //跨月则设置为月末
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }
                SPDB01Header tmpBnkHeader = new SPDB01Header();
                tmpBnkHeader.transCode = "8924";
                int queryNumber = 20;//查询的笔数
                int beginNumber = -1;//查询的起始笔数
                int totalCount = 0;
                while (beginNumber <= totalCount && tmpRespCode.length() == 0) {//分页查询

                    if (beginNumber < 0) {
                        beginNumber = 1;
                    }

                    XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    xmlWriter.autoFormat = false;
                    xmlWriter.writeStartElement("body");
                    xmlWriter.writeElementString("acctNo", p_req7516.actNum);
                    xmlWriter.writeElementString("beginDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    xmlWriter.writeElementString("endDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));

                    xmlWriter.writeElementString("queryNumber", String.valueOf(queryNumber));
                    xmlWriter.writeElementString("beginNumber", String.valueOf(beginNumber));
                    xmlWriter.writeEndDocument();

                    String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), tmpBnkHeader);
                    XmlTextReader tmpBkReader;

                    if (tmpStrRet[0].length() > 0) {//判断通讯是否失败
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpStrRet[1];
                        break;
                    }
                    StringBuilder tmpSbMsg = new StringBuilder();
                    tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader == null) {//判断加载xml是否成功
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                        break;
                    }
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if (StringHelper.isNullOrEmpty(returnMsg)) {
                        returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                    }
                    if (returnCode == null || !returnCode.equals("AAAAAAA")) {//判断报文是否无效
                        if (returnCode.equals("EGG0521")) {
                            //tmpRespCode = "0";
                            WriteBankLogLn(tmpIntDateFrom + ":" + returnMsg);
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = returnMsg;
                        }
                        break;
                    }
                    String bkStrTotalCount = tmpBkReader.getFirstText("/packet/body/totalCount");
                    if (StringHelper.isNullOrEmpty(bkStrTotalCount)) {
                        break;
                    }
                    int totalCountCmp = Integer.parseInt(bkStrTotalCount);
                    if (totalCount == 0) {
                        totalCount = totalCountCmp;
                    }
                    if (totalCount != totalCountCmp) {
                        tmpRespCode = "-1";
                        tmpRespInfo = "相同条件银行返回的总笔数" + totalCountCmp + "与上次" + totalCount + "不相同";
                        break;
                    }

                    String acctNo = tmpBkReader.getFirstText("/packet/body/acctNo");
                    String currency = tmpBkReader.getFirstText("/packet/body/currency");
                    if (StringHelper.isNullOrEmpty(acctNo)) {
                        acctNo = p_req7516.actNum;
                    }
                    int tmpRdCount = 0;
                    while (tmpBkReader.read("/packet/body/lists/list")) {
                        tmpRdCount++;
                        RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                        tmpRetDetail.actNum = acctNo;
                        if (StringHelper.hasAnyChar(currency)) {
                            tmpRetDetail.cur = this.convertCurToATS(currency);
                        }
                        tmpRetDetail.accBal = tmpBkReader.readedXElement.getSingleText("balance");
                        String txAmount = tmpBkReader.readedXElement.getSingleText("txAmount");
                        String tranFlag = tmpBkReader.readedXElement.getSingleText("tranFlag");

                        if (tranFlag.equals("0")) {//0：借     1：贷
                            tmpRetDetail.cdFlag = "1";
                            if (txAmount.indexOf("-") >= 0) {
                                tmpRetDetail.cdFlag = "2";
                            }
                        } else if (tranFlag.equals("1")) {
                            tmpRetDetail.cdFlag = "2";
                            if (txAmount.indexOf("-") >= 0) {
                                tmpRetDetail.cdFlag = "1";
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "银行返回的借贷标志不符合预期";
                            break;
                        }
                        tmpRetDetail.tranAmt = txAmount.replace("-", "");
                        String transDate = tmpBkReader.readedXElement.getSingleText("transDate");
                        if (transDate.length() == 8) {
                            tmpRetDetail.tranDate = transDate.substring(0, 4) + "-" + transDate.substring(4, 6) + "-" + transDate.substring(6, 8);
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "银行返回的交易日期" + transDate + "格式不符合预期";
                            break;
                        }
                        String transTime = tmpBkReader.readedXElement.getSingleText("transTime");
                        if (transTime.length() < 6) {
                            transTime = StringHelper.padLeft(transTime, 6, '0');
                        }
                        if (transTime.length() == 6) {
                            tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " + transTime.substring(0, 2) + ":" + transTime.substring(2, 4) + ":" + transTime.substring(4, 6);
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "银行返回的交易时间格式" + tmpBkReader.readedXElement.getSingleText("transTime") + "不符合预期";
                            break;
                        }
                        tmpRetDetail.valueDate = tmpRetDetail.tranDate;


                        tmpRetDetail.recAccBank = tmpBkReader.readedXElement.getSingleText("payeeBankName");
                        if (StringHelper.isNullOrEmpty(tmpRetDetail.recAccBank)) {
                            tmpRetDetail.recAccBank = tmpBkReader.readedXElement.getSingleText("payeeBankNo");
                        }

                        tmpRetDetail.recAccNum = tmpBkReader.readedXElement.getSingleText("payeeAcctNo");
                        if (StringHelper.isNullOrEmpty(tmpRetDetail.recAccNum)) {
                            tmpRetDetail.recAccNum = tmpBkReader.readedXElement.getSingleText("customerAcctNo");
                        }
                        tmpRetDetail.recAccName = tmpBkReader.readedXElement.getSingleText("payeeName");
                        tmpRetDetail.originator = tmpBkReader.readedXElement.getSingleText("seqNo");
                        tmpRetDetail.payCode = tmpBkReader.readedXElement.getSingleText("voucherNo");
                        tmpRetDetail.usage = tmpBkReader.readedXElement.getSingleText("note");
                        tmpRetDetail.comment = tmpBkReader.readedXElement.getSingleText("remark");
                        tmpRetDetail.seqId = StringHelper.joinNotEmpty("", tmpBkReader.readedXElement.getSingleText("seqNo"), tmpBkReader.readedXElement.getSingleText("seqNum"));
                        //DSPJAVA-11767 【君康人寿】浦发明细问题/Fantx@2020年4月23日
                        nodeAnalysic(tmpBkReader.readedXElement, tmpRetDetail, getCharset());//根据配置将 银行返回字段summary 分割赋值给对账码和用途
                        retAts.writeRetDetail(tmpRetDetail);
                    }
                    beginNumber += tmpRdCount;
                    if (tmpRdCount == 0) {
                        break;
                    }
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    //当日明细查询调用历史明细查询方法
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        //通用b2e0035
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);
        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;
        String tmpStrToday = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;
        return d_7516_HisTrans(tmpReq7516);
    }
}
